#include<iostream>
#include<string>
#include<cstring>
#include<sys/types.h>
#include<sys/socket.h>
#include<netinet/in.h>
#include<arpa/inet.h>
#include<unistd.h>

#include"thread.hpp"

using namespace ThreadModle;

int InitClient()
{
    int socketfd=::socket(AF_INET,SOCK_DGRAM,0);
    if(socketfd<0)
    {
        std::cerr<<"creat socket fail"<<std::endl;
        exit(1);
    }
    return socketfd;
}

void RecvMessage(int socketfd,const std::string& name)
{
    while(true)
    {
        struct sockaddr_in peer;
        socklen_t len=sizeof(peer);
        char inbuff[1024];
        int m=recvfrom(socketfd,inbuff,sizeof(inbuff)-1,0,(struct sockaddr*)&peer,&len);
        if(m>0)
        {
            inbuff[m]=0;
            std::cout<<inbuff<<std::endl;
        }
        else
        {
            break;
        }
    }
}
void SendMessage(const std::string serverip,uint16_t serverport,int socketfd,const std::string& name)
{
    struct sockaddr_in server;
    memset(&server,0,sizeof(server));
    server.sin_family=AF_INET;
    server.sin_port=htons(serverport);
    server.sin_addr.s_addr=inet_addr(serverip.c_str());

    while(true)
    {
        std::string mes;
        std::cout<<"please enter message :";
        std::getline(std::cin,mes);

        int n=sendto(socketfd,mes.c_str(),mes.size(),0,(struct sockaddr*)&server,sizeof(server));
        if(n<=0)break;
    }
}

int main(int argc,char* argv[])
{
    if(argc!=3)
    {
        std::cerr<<"Usage: "<<argv[0]<<" server-ip server-port"<<std::endl;
        exit(1);
    }
    int socketfd=InitClient();
    std::string serverip=argv[1];
    uint16_t serverport=std::stoi(argv[2]);

    Thread recver("recv_thread",std::bind(&RecvMessage,socketfd,std::placeholders::_1));
    Thread sender("send_thread",std::bind(&SendMessage,serverip,serverport,socketfd,std::placeholders::_1));

    recver.Start();
    sender.Start();

    recver.Join();
    sender.Join();



    
    ::close(socketfd);
    return 0;
}
